package org.zfes.snowier.cloud.zbss.cms.column.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.zfes.snowier.core.data.DataSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.zfes.snowier.core.util.ZBeanUtil;
import org.zfes.snowier.core.util.ZDateUtil;
import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.common.dao.params.ParamMap;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnCountService;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnGroupContributeService;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnGroupViewService;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnService;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnTxtService;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnUserDefineAttrService;
import org.zfes.snowier.cloud.zbss.cms.column.service.ICmsColumnUserService;
import org.zfes.snowier.cloud.zbss.cms.model.dto.CmsModelDto;
import org.zfes.snowier.cloud.zbss.cms.model.service.ICmsModelService;
import org.zfes.snowier.cloud.zbss.cms.template.model.CmsTemplate;
import org.zfes.snowier.cloud.zbss.cms.template.service.ICmsTemplateService;
import org.zfes.snowier.cloud.zbss.cms.zconfig.ZConfig;
import org.zfes.snowier.cloud.zbss.cms.column.dao.CmsColumnMapper;
import org.zfes.snowier.cloud.zbss.cms.column.dto.CmsColumnCreateDto;
import org.zfes.snowier.cloud.zbss.cms.column.model.CmsColumn;
import org.zfes.snowier.cloud.zbss.cms.column.model.CmsColumnTxt;

import java.util.stream.Stream;
@Service
public class CmsColumnServiceImpl implements ICmsColumnService{
 	@Autowired
	private CmsColumnMapper cmsColumnMapper;
 	@Autowired
	private ICmsColumnTxtService cmsColumnTxtService;
 	@Autowired
 	private ICmsColumnUserDefineAttrService cmsColumnUserDefineAttrService;
    @Autowired
    private ICmsTemplateService cmsTemplateService;
 	@Autowired
 	private ICmsModelService cmsModelService;
 	@Autowired
 	private ICmsColumnUserService cmsColumnUserService;
 	@Autowired
 	private ICmsColumnGroupViewService cmsColumnGroupViewService;
    @Autowired
    private ICmsColumnGroupContributeService cmsColumnGroupContributeService;
    @Autowired
    private ICmsColumnCountService cmsColumnCountService;
 	
	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void createCmsColumn(CmsColumnCreateDto columnCreateDto,Map<String ,String> userDefineAttrMap) {
		//参数校验
 		String columnName=columnCreateDto.getColumnName();
 		ZAssert.notNull(columnName, "请填写栏目名称");
 		
 		String columnPath=columnCreateDto.getColumnPath();
 		ZAssert.notNull(columnPath, "请填写栏目访问路径");
 		
 		//整型参数校验
 		int pageSize=columnCreateDto.getPageSize();
 		ZAssert.bigThanZero(pageSize, "", "每页记录数错误");
 		
 		//未找到上级栏目
 		Long parentId=columnCreateDto.getParentId();
 		Optional<CmsColumn> columnOp=loadCmsColumnById(parentId);
 		ZAssert.notEmpty(columnOp, "未查询到该上级栏目数据");
		ZAssert.equals(columnOp.get().getStatus(), Byte.valueOf("1"), "该上级栏目已经被删除或者禁用");
 	
		//未找到栏目模板
		Long tplColumnId=columnCreateDto.getTplColumnId();
		Optional<CmsTemplate> templateOp=cmsTemplateService.loadCmsTemplateById(tplColumnId);
		ZAssert.notEmpty(templateOp, "未查询到该栏目模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该栏目模板已被删除或禁用");//状态:_D#1 启用 0禁用 -1删除#
		
		//未找到栏目手机模板
		Long tplMobileColumnId=columnCreateDto.getTplMobileColumnId();
		templateOp=cmsTemplateService.loadCmsTemplateById(tplMobileColumnId);
		ZAssert.notEmpty(templateOp, "未查询到该栏目手机模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该栏目手机模板已被删除或禁用");
		
		//未找到内容模板
		Long tplContentId = columnCreateDto.getTplContentId();
		templateOp=cmsTemplateService.loadCmsTemplateById(tplContentId);
		ZAssert.notEmpty(templateOp, "未查询到该内容模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该内容模板已被删除或禁用");
		
		//未找到内容手机模板
		Long tplMobileContentId = columnCreateDto.getTplMobileContentId();
		templateOp=cmsTemplateService.loadCmsTemplateById(tplMobileContentId);
	    ZAssert.notEmpty(templateOp, "未查询到该内容手机模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该内容手机模板已被删除或禁用");
		
		//column初始化
		CmsColumn cmsColumn = new CmsColumn();
		ZBeanUtil.copy(columnCreateDto, cmsColumn, true);
		ZBeanUtil.setCreateInfo(cmsColumn);
		cmsColumn.setSiteId(ZConfig.siteId);
		
		//找到上级栏目，查看上级栏目树形编码
		String parentColumnTreeCode = columnOp.get().getColumnTreeCode();
		
		//查看已有同属该栏目的同级栏目数
		int sameLevelCount=cmsColumnMapper.selectSubColumnCountByColumnTreeCode(parentColumnTreeCode);
		
		//生成树形编码
		cmsColumn.setColumnTreeCode(parentColumnTreeCode+"_"+String.format("%04d",sameLevelCount));
		
		//根据model的定义校验数据
		Optional<CmsModelDto> cmsModelDtoOp = cmsModelService.loadCmsModelDtoById(columnCreateDto.getModelId());
		validateByModel(cmsModelDtoOp.get(), cmsColumn, userDefineAttrMap);		
		
		//创建column
		Long columnId=createCmsColumn(cmsColumn);
		
		//向column_user_define_attr表中添加记录
		cmsColumnUserDefineAttrService.createAndUpdateCmsColumnUserDefineAttr(columnId, userDefineAttrMap);
		
		//向column_txt表中添加记录
		if(userDefineAttrMap.containsKey("txt")) {
			CmsColumnTxt columnTxt = new CmsColumnTxt();
			ZBeanUtil.setCreateInfo(columnTxt);
			columnTxt.setColumnId(columnId);
			columnTxt.setTxt1(userDefineAttrMap.get("txt"));
			if(userDefineAttrMap.containsKey("txt1"))
				columnTxt.setTxt1(userDefineAttrMap.get("txt1"));
			if(userDefineAttrMap.containsKey("txt2"))
				columnTxt.setTxt1(userDefineAttrMap.get("txt2"));
			if(userDefineAttrMap.containsKey("txt3"))
				columnTxt.setTxt1(userDefineAttrMap.get("txt3"));
			cmsColumnTxtService.createCmsColumnTxt(columnTxt);
		}
		//向cms_column_group_view表中添加记录
		if(userDefineAttrMap.containsKey("viewgroupids")) {
			cmsColumnGroupViewService.createCmsColumnGroupView(columnId,userDefineAttrMap.get("viewgroupids"));
		}
		//向cms_column_group_contribute表中添加记录
		if(userDefineAttrMap.containsKey("contrigroupids")) {	
			cmsColumnGroupContributeService.createCmsColumnGroupContribute(columnId,userDefineAttrMap.get("contrigroupids") );
		}
	}
 	@Transactional(rollbackFor=Exception.class)
 	@Override
	public Long createCmsColumn(CmsColumn cmsColumn) {
 		ZBeanUtil.setCreateInfo(cmsColumn);
 		ZBeanUtil.validateBean(cmsColumn);
		cmsColumnMapper.insertSelective(cmsColumn);
		return cmsColumn.getId();
	}
 	
 	
 	//===========查看
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<CmsColumn> loadCmsColumnById(Long id) {
		if(id!=null){
			return Optional.ofNullable(cmsColumnMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<CmsColumn> loadCmsColumn() {
		return cmsColumnMapper.loadCmsColumn();
	}

	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public DataSet loadCmsColumnDataSet(Map<String, Object> params) {
		ParamMap pm=ParamMap.filterParam(params);
		DataSet ds=DataSet.newDS2(cmsColumnMapper.selectListCount(pm), cmsColumnMapper.selectMapListPage(pm));
		return ds;
	}

	//获取用户已订阅和未订阅的栏目
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Map<String, List<CmsColumn>> loadColumnIdSubscribeAndNot(Long userId) {
		ZAssert.notNull(userId, "userId不能为空");
		
		//创建List
		List<CmsColumn> subscribeColumnList=new ArrayList<CmsColumn>();
		List<CmsColumn> notSubscribeColumnList=new ArrayList<CmsColumn>();
		
		//加载所有栏目列表
		List<CmsColumn> cmsColumnList=cmsColumnMapper.loadCmsColumn();
		
		//加载所有用户已订阅栏目id
		List<Long> subscribeColumnIdList = cmsColumnUserService.loadColumnIdByUserId(userId);
		
		//根据用户已订阅栏目id列表，生成用户已订阅及未订阅栏目表
		for(int i=0;i<cmsColumnList.size();i++) {
			Long columnId=cmsColumnList.get(i).getId();
			if(subscribeColumnIdList.contains(columnId)) {//该栏目已订阅
				subscribeColumnList.add(cmsColumnList.get(i));
			}
			else
				notSubscribeColumnList.add(cmsColumnList.get(i));
		}
		
		//创建map
		Map<String, List<CmsColumn>> columnMap=new HashMap<String,List<CmsColumn>>();
		columnMap.put("subscribeColumnList", subscribeColumnList);
		columnMap.put("notSubscribeColumnList", notSubscribeColumnList);
		
		return columnMap;
	}

	
	//==============更新
	@Override
	@Transactional(rollbackFor=Exception.class)
	public void updateCmsColumn(Long columnId,CmsColumnCreateDto columnCreateDto,Map<String,String> userDefineAttrMap) {
		ZAssert.notNull(columnId, "栏目Id参数错误");
		ZBeanUtil.validateBean(columnCreateDto);
		//参数校验
 		String columnName=columnCreateDto.getColumnName();
 		ZAssert.notNull(columnName, "请填写栏目名称");
 		
 		String columnPath=columnCreateDto.getColumnPath();
 		ZAssert.notNull(columnPath, "请填写栏目访问路径");
 		
 		//整型参数校验
 		int pageSize=columnCreateDto.getPageSize();
 		ZAssert.bigThanZero(pageSize, "", "每页记录数错误");
 		
 		//未找到上级栏目
 		Long parentId=columnCreateDto.getParentId();
 		Optional<CmsColumn> columnOp=loadCmsColumnById(parentId);
 		ZAssert.notEmpty(columnOp, "未查询到该上级栏目数据");
		ZAssert.equals(columnOp.get().getStatus(), Byte.valueOf("1"), "该上级栏目已经被删除或者禁用");
 	
		//未找到栏目模板
		Long tplColumnId=columnCreateDto.getTplColumnId();
		Optional<CmsTemplate> templateOp=cmsTemplateService.loadCmsTemplateById(tplColumnId);
		ZAssert.notEmpty(templateOp, "未查询到该栏目模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该栏目模板已被删除或禁用");//状态:_D#1 启用 0禁用 -1删除#
		
		//未找到栏目手机模板
		Long tplMobileColumnId=columnCreateDto.getTplMobileColumnId();
		templateOp=cmsTemplateService.loadCmsTemplateById(tplMobileColumnId);
		ZAssert.notEmpty(templateOp, "未查询到该栏目手机模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该栏目手机模板已被删除或禁用");
		
		//未找到内容模板
		Long tplContentId = columnCreateDto.getTplContentId();
		templateOp=cmsTemplateService.loadCmsTemplateById(tplContentId);
		ZAssert.notEmpty(templateOp, "未查询到该内容模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该内容模板已被删除或禁用");
		
		//未找到内容手机模板
		Long tplMobileContentId = columnCreateDto.getTplMobileContentId();
		templateOp=cmsTemplateService.loadCmsTemplateById(tplMobileContentId);
	    ZAssert.notEmpty(templateOp, "未查询到该内容手机模板");
		ZAssert.equals(templateOp.get().getStatus(),Byte.valueOf("1"), "该内容手机模板已被删除或禁用");
		
		//根据model的定义校验数据		
		CmsColumn cmsColumn=cmsColumnMapper.selectByPrimaryKey(columnId);
		ZBeanUtil.copy(columnCreateDto, cmsColumn, true);
		
		Optional<CmsModelDto> cmsModelDtoOp = cmsModelService.loadCmsModelDtoById(columnCreateDto.getModelId());
		validateByModel(cmsModelDtoOp.get(), cmsColumn, userDefineAttrMap);		
		
		//更新cms_column中记录
		cmsColumnMapper.update(cmsColumn);
		
		//删除cms_column_user_define_Attr表中记录
		cmsColumnUserDefineAttrService.updateCmsColumnUserDefineAttrStatusByColumnId(columnId, Byte.valueOf("-1"));;
		//cms_column_user_define_Attr表中添加新的记录
		cmsColumnUserDefineAttrService.createAndUpdateCmsColumnUserDefineAttr(columnId, userDefineAttrMap);
		
		//更新column_txt表中记录
		if(userDefineAttrMap.containsKey("txt")) {
			CmsColumnTxt columnTxt = new CmsColumnTxt();
			ZBeanUtil.setCreateInfo(columnTxt);
			columnTxt.setColumnId(columnId);
			columnTxt.setTxt1(userDefineAttrMap.get("txt"));
			if(userDefineAttrMap.containsKey("txt1"))
				columnTxt.setTxt1(userDefineAttrMap.get("txt1"));
				if(userDefineAttrMap.containsKey("txt2"))
					columnTxt.setTxt1(userDefineAttrMap.get("txt2"));
				if(userDefineAttrMap.containsKey("txt3"))
					columnTxt.setTxt1(userDefineAttrMap.get("txt3"));
				cmsColumnTxtService.updateCmsColumnTxt(columnTxt);;
		}
		//更新cms_column_group_view表中记录
		if(userDefineAttrMap.containsKey("viewgroupids")) {
			//物理删除原有记录
			cmsColumnGroupViewService.deleteCmsColumnGroupViewByColumnId(columnId);
			//添加新记录
			cmsColumnGroupViewService.createCmsColumnGroupView(columnId,userDefineAttrMap.get("viewgroupids"));
		}
		//更新cms_column_group_contribute表中记录
		if(userDefineAttrMap.containsKey("contrigroupids")) {
			//物理删除原有记录
			cmsColumnGroupContributeService.deleteCmsColumnGroupContributeByColumnId(columnId);
			//添加新记录
			cmsColumnGroupContributeService.createCmsColumnGroupContribute(columnId,userDefineAttrMap.get("contrigroupids") );
		}
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public void updateCmsColumn(CmsColumn column) {
		ZBeanUtil.validateBean(column);
		column.setUpdateTime(ZDateUtil.newDate());
		cmsColumnMapper.update(column);
	}
	
	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void deleteCmsColumn(Long id) {
		ZAssert.notNull(id, "请选择要操作的数据");
		cmsColumnMapper.updateStatus(id, Byte.valueOf("-1"));
		cmsColumnTxtService.updateCmsColumnTxtStatusByColumnId(id, Byte.valueOf("-1"));
		
		//cmsColumnUserDefineAttr表中相关记录逻辑删除
		cmsColumnUserDefineAttrService.updateCmsColumnUserDefineAttrStatusByColumnId(id,Byte.valueOf("-1"));
	   
		//cms_column_user表中相关记录物理删除
		cmsColumnUserService.deleteByColumnId(id);
		
		//cms_column_count表中相关记录逻辑删除
		cmsColumnCountService.setCmsColumnCountStatusByColumnId(id, Byte.valueOf("-1"));
		//cms_column_txt表中相关记录逻辑删除
		cmsColumnTxtService.updateCmsColumnTxtStatusByColumnId(id, Byte.valueOf("-1"));
		//cms_column_group_view表中相关记录逻辑删除
		cmsColumnGroupViewService.setCmsColumnGroupViewStatusByColumnId(id,Byte.valueOf("-1"));
		//cms_column_group_contribute表中相关记录逻辑删除
		cmsColumnGroupContributeService.setCmsColumnGroupContributeStatusByColumnId(id, Byte.valueOf("-1"));;
	}
	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void setCmsColumnStatus(Long id, Byte status) {
		ZAssert.notNull(id, "请选择要操作的数据");
		ZAssert.notNull(status, "状态参数错误");
		if(!Stream.of(new Byte[] {-1,0,1}).anyMatch(val->val.equals(status))) {
			ZAlert.serviceLogicalError("状态参数错误");
		}
		cmsColumnMapper.updateStatus( id,  status) ;
	}
	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void updateCmsColumnSortNum(Long columnId, int sortNum) {
		ZAssert.notNull(columnId, "请选择要操作的数据");
		ZAssert.notNull(sortNum, "请选择要操作的数据");
		cmsColumnMapper.updateCmsColumnSortNum(columnId, sortNum);
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<Long> loadColumnIdByIsDefault(Byte isDefault) {
		if(!Stream.of(new Byte[] {0,1}).anyMatch(val->val.equals(isDefault))) {
			ZAlert.serviceLogicalError("参数错误");
		}
		List<Long> columnIdList=cmsColumnMapper.loadColumnIdByIsDefault(isDefault);
		return columnIdList;
	}
	
}